ডেটাবেসের Concurrency Control এর জন্য Optimistic Locking এবং Pessimistic Locking ব্যবহৃত হয়। Spring ORM এ এগুলো Hibernate এবং JPA এর মাধ্যমে ইমপ্লিমেন্ট করা যায়। এই লকিং মেকানিজম নিশ্চিত করে যে ডেটা একাধিক থ্রেড বা ট্রানজ্যাকশন দ্বারা একসঙ্গে পরিবর্তিত হলে ডেটা সঠিক থাকে।
Optimistic Locking ধরে নেয় যে ডেটার অ্যাক্সেসের সময় কনফ্লিক্টের সম্ভাবনা কম। এটি ডেটার পরিবর্তনের সময় যাচাই করে কোনো কনফ্লিক্ট হয়েছে কিনা।
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@Version
private int version;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductPrice(Long productId, Double newPrice) {
Product product = productRepository.findById(productId).orElseThrow();
product.setPrice(newPrice);
productRepository.save(product);
}
}
Pessimistic Locking ধরে নেয় যে ডেটার অ্যাক্সেসের সময় কনফ্লিক্ট হওয়ার সম্ভাবনা বেশি। এটি ডেটার অ্যাক্সেসের সময় সরাসরি Lock প্রয়োগ করে।
import jakarta.persistence.LockModeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductPriceWithLock(Long productId, Double newPrice) {
Product product = productRepository.findByIdWithLock(productId);
product.setPrice(newPrice);
productRepository.save(product);
}
}
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
public interface ProductRepository extends JpaRepository<Product, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT p FROM Product p WHERE p.id = :id")
Product findByIdWithLock(Long id);
}
বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
---|---|---|
কনফ্লিক্টের সম্ভাবনা | কম (Low) | বেশি (High) |
লকিং টাইপ | ভার্চুয়াল (Version Number দিয়ে) | সরাসরি ডেটার উপর Lock আরোপ |
পারফরম্যান্স | তুলনামূলকভাবে ভালো | ধীর (লক আরোপ করার কারণে) |
ব্যবহারিক উদাহরণ | Read-heavy অ্যাপ্লিকেশন | Write-heavy বা ট্রানজ্যাকশন-ইনটেনসিভ সিস্টেম |
Optimistic Locking এবং Pessimistic Locking Spring ORM-এConcurrency Management নিশ্চিত করতে ব্যবহৃত হয়। Optimistic Locking সাধারণত read-heavy অ্যাপ্লিকেশনগুলোর জন্য কার্যকর এবং Pessimistic Locking write-heavy সিস্টেমে ব্যবহৃত হয়। সঠিক পরিস্থিতিতে সঠিক মেথড ব্যবহার করা ডেটার নির্ভুলতা ও পারফরম্যান্স নিশ্চিত করে।
Locking ডাটাবেসের এমন একটি প্রক্রিয়া যা একাধিক ব্যবহারকারী বা প্রসেস যখন একই ডেটা অ্যাক্সেস বা পরিবর্তন করার চেষ্টা করে, তখন ডেটার সঠিকতা এবং সামঞ্জস্য নিশ্চিত করে। এটি বিশেষত Concurrency Control এর জন্য ব্যবহৃত হয়, যেখানে একই ডেটার উপর একাধিক অপারেশন পারফর্ম করা হয়।
Hibernate এবং JPA-তে Locking প্রধানত দুই প্রকার:
Optimistic Locking ধরে নেয় যে ডেটার উপর কনফ্লিক্ট খুব কম হয়। এটি কোনো লক নেয় না; বরং একটি Version বা Timestamp ফিল্ড ব্যবহার করে ডেটার সামঞ্জস্যতা যাচাই করে।
কাজের পদ্ধতি:
উদাহরণ:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Version
private int version;
// Getters and Setters
}
Pessimistic Locking ধরে নেয় যে ডেটার উপর কনফ্লিক্ট হতে পারে এবং ডেটা রিড বা রাইট করার সময় তা লক করে রাখে।
কাজের পদ্ধতি:
উদাহরণ:
// Pessimistic Read Lock
entityManager.lock(product, LockModeType.PESSIMISTIC_READ);
// Pessimistic Write Lock
entityManager.lock(product, LockModeType.PESSIMISTIC_WRITE);
Locking নিশ্চিত করে যে একই ডেটা একাধিক ট্রানজেকশন দ্বারা পরিবর্তিত হলে ডেটা ইনকনসিস্টেন্সি না হয়।
Concurrency এর কারণে ডেটা রেস (যখন একাধিক প্রসেস ডেটা অ্যাক্সেস করে) হতে পারে। Locking এই সমস্যাগুলো প্রতিরোধ করে।
Locking নিশ্চিত করে যে কোনো একটি ট্রানজেকশন শেষ না হওয়া পর্যন্ত অন্য ট্রানজেকশন সেই ডেটা পরিবর্তন করতে পারবে না।
Locking ব্যবহার করে Dirty Read, Non-repeatable Read, এবং Phantom Read এর মতো সমস্যা প্রতিরোধ করা যায়।
বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
---|---|---|
লক প্রক্রিয়া | কোনো লক নেয় না, ভার্সন বা টাইমস্ট্যাম্প ব্যবহার করে | ডেটার উপর সরাসরি লক প্রয়োগ করে |
কনফ্লিক্টের সম্ভাবনা | কম কনফ্লিক্ট থাকলে কার্যকর | বেশি কনফ্লিক্ট থাকলে কার্যকর |
কর্মক্ষমতা (Performance) | ভালো, কারণ লক ব্যবস্থাপনা প্রয়োজন নেই | বেশি রিসোর্স ব্যবহার করে |
ব্যবহারের ক্ষেত্র | বেশি রিড অপারেশন এবং কম কনফ্লিক্ট | বেশি রাইট অপারেশন এবং বেশি কনফ্লিক্ট |
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private double balance;
@Version
private int version;
// Getters and Setters
}
@Transactional
public Account withdrawAmount(Long accountId, double amount) {
Account account = entityManager.find(Account.class, accountId, LockModeType.PESSIMISTIC_WRITE);
if (account.getBalance() >= amount) {
account.setBalance(account.getBalance() - amount);
} else {
throw new InsufficientBalanceException("Insufficient balance.");
}
return account;
}
@Transactional
public Account updateAccount(Account updatedAccount) {
try {
return accountRepository.save(updatedAccount);
} catch (OptimisticLockingFailureException e) {
throw new ConcurrentModificationException("The account was updated by another transaction.");
}
}
Locking একটি অপরিহার্য প্রক্রিয়া যা ডেটাবেস ট্রানজেকশন এবং কনকারেন্সি সমস্যাগুলো সমাধান করতে সাহায্য করে। Optimistic Locking এবং Pessimistic Locking এর মধ্যে পার্থক্য বুঝে প্রয়োজন অনুযায়ী ব্যবহার করলে ডেটার অখণ্ডতা এবং সামঞ্জস্যতা বজায় রাখা সহজ হয়।
Spring ORM-এ Optimistic Locking এবং Pessimistic Locking হল কনকারেন্সি কন্ট্রোল মেকানিজম, যা ডাটাবেস অ্যাক্সেস করার সময় ডেটার সঠিকতা নিশ্চিত করে। ডেটা পরিবর্তনের সময় মাল্টিপল ট্রানজ্যাকশনের মধ্যে সংঘর্ষ এড়ানোর জন্য এগুলো ব্যবহৃত হয়।
Optimistic Locking হল এমন একটি পদ্ধতি যেখানে ধরে নেওয়া হয়, একই ডেটা একই সময়ে অন্য কেউ আপডেট করবে না। এটি ডেটা আপডেটের আগে চেক করে, ডেটা পরিবর্তিত হয়েছে কিনা।
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@Version
private int version;
// Getters and Setters
}
version
ফিল্ডটি Hibernate দ্বারা স্বয়ংক্রিয়ভাবে পরিচালিত হয়।version
যাচাই করে।version
মিলে না যায়, তখন OptimisticLockException নিক্ষেপ করা হয়।Pessimistic Locking এমন একটি পদ্ধতি যেখানে ধরে নেওয়া হয়, একই ডেটা অন্য কেউ একসাথে আপডেট করতে পারে। এটি প্রতিরোধ করার জন্য, ডেটা পড়ার বা লেখার সময় লক প্রয়োগ করা হয়।
public Product findWithPessimisticLock(Long id) {
return entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE);
}
PESSIMISTIC_READ
: রিড অপারেশন লক করে, তবে ডেটা পরিবর্তন করতে দেয় না।PESSIMISTIC_WRITE
: রাইট অপারেশন লক করে, অন্য ট্রানজ্যাকশনকে সম্পূর্ণ ব্লক করে।PESSIMISTIC_FORCE_INCREMENT
: রাইটের সাথে সাথে version
ইনক্রিমেন্ট করে।প্যারামিটার | Optimistic Locking | Pessimistic Locking |
---|---|---|
লকিং কৌশল | লক প্রয়োগ করা হয় না। | লক প্রয়োগ করা হয়। |
কনফ্লিক্ট সমাধান | Version বা Timestamp দিয়ে সংঘর্ষ নির্ধারণ। | ট্রানজ্যাকশন লক দিয়ে সংঘর্ষ প্রতিরোধ। |
Deadlock এর ঝুঁকি | Deadlock এর কোনো ঝুঁকি নেই। | Deadlock এর ঝুঁকি রয়েছে। |
পারফরম্যান্স | বেশি পড়া-লেখা কার্যক্রমে ভালো পারফরম্যান্স। | বেশি লেখার কার্যক্রমে কার্যকর। |
ব্যবহারিক ক্ষেত্র | কম কনকারেন্ট রাইট অপারেশনের জন্য উপযুক্ত। | বেশি কনকারেন্ট রাইট অপারেশনের জন্য উপযুক্ত। |
ব্যবহার | @Version ব্যবহার করে সহজে কনফিগার করা যায়। | LockModeType ব্যবহার করে কনফিগার করতে হয়। |
try {
product.setPrice(500.0);
productRepository.save(product);
} catch (OptimisticLockException e) {
System.out.println("Concurrency conflict detected!");
}
@Transactional
public Product updateProduct(Long id, double newPrice) {
Product product = entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE);
product.setPrice(newPrice);
return product;
}
Spring ORM এ Locking মেকানিজম সঠিকভাবে ব্যবহার করলে ডেটা ইন্টেগ্রিটি নিশ্চিত করা যায় এবং অ্যাপ্লিকেশনের কনকারেন্সি সমস্যা এড়ানো সম্ভব হয়।
Spring ORM এবং Hibernate ব্যবহার করে ডাটাবেসের কনকারেন্সি (concurrency) ম্যানেজ করতে @Version অ্যানোটেশন একটি কার্যকরী উপায়। এটি Optimistic Locking বাস্তবায়নে ব্যবহৃত হয়, যা ডাটাবেসে মাল্টিপল ট্রানজ্যাকশনের সময় ডেটা কনসিস্টেন্সি বজায় রাখে।
Optimistic Locking একটি কৌশল যেখানে ডেটা রিড করার সময় ধরে নেওয়া হয় যে ডেটা অন্য কেউ পরিবর্তন করবে না। তবে, আপডেট করার সময় চেক করা হয় ডেটার সংস্করণ (version) পরিবর্তন হয়েছে কি না। যদি পরিবর্তন হয়ে থাকে, তাহলে কনফ্লিক্ট (conflict) ম্যানেজ করতে উপযুক্ত পদক্ষেপ নেওয়া হয়।
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
@Entity
public class Product {
@Id
private int id;
private String name;
private double price;
@Version
private int version;
// Getter এবং Setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
টেবিলের জন্য একটি version
বা অনুরূপ কলাম যুক্ত করুন। উদাহরণস্বরূপ:
ALTER TABLE Product ADD version INT DEFAULT 0;
Hibernate স্বয়ংক্রিয়ভাবে এই কলামের মান পরিচালনা করবে।
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class ProductService {
private EntityManagerFactory emf;
public ProductService() {
emf = Persistence.createEntityManagerFactory("example-unit");
}
public void updateProductPrice(int productId, double newPrice) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
Product product = em.find(Product.class, productId);
product.setPrice(newPrice);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
e.printStackTrace();
} finally {
em.close();
}
}
}
যদি একই ডেটা দুইটি ট্রানজ্যাকশন দ্বারা আপডেট করা হয়, তাহলে একটি OptimisticLockException থ্রো হবে, যা নিচের মতো হ্যান্ডেল করা যেতে পারে:
try {
updateProductPrice(1, 150.0);
} catch (OptimisticLockException e) {
System.out.println("Concurrency issue detected! Please retry.");
}
Spring ORM-এ @Version অ্যানোটেশনের মাধ্যমে Optimistic Locking ব্যবহার করে মাল্টিপল ট্রানজ্যাকশন পরিচালনার সময় ডেটার অখণ্ডতা নিশ্চিত করা যায়। এটি একটি কার্যকর এবং ব্যবহার-বান্ধব কৌশল যা Spring ORM বা Hibernate-এর পারফরম্যান্স ও নির্ভরযোগ্যতা বৃদ্ধি করে।
Spring ORM এ Locking ব্যবহার করা হয় কনকারেন্সি কন্ট্রোলের জন্য, যাতে একই ডেটার উপর একাধিক ট্রানজ্যাকশন সঠিকভাবে পরিচালনা করা যায়। Hibernate বা JPA-তে Locking মেকানিজম ডেটাবেস লেভেলে ডেটার কনসিস্টেন্সি নিশ্চিত করে।
Hibernate দুটি ধরনের লকিং সরবরাহ করে:
Optimistic Locking তখন ব্যবহৃত হয় যখন ডেটার সংঘর্ষ (conflict) খুব কম হয়। এটি ডেটা আপডেট করার আগে একটি ভার্সন চেক করে সংঘর্ষ প্রতিরোধ করে।
@Version
ব্যবহারimport jakarta.persistence.*;
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "price")
private Double price;
@Version
private Integer version; // Version field for Optimistic Locking
// Getters and Setters
}
ব্যাখ্যা:
@Version
অ্যানোটেশনটি Hibernate বা JPA-কে বলে দেয়, ট্রানজ্যাকশন চলাকালে ডেটার একটি ভার্সন ট্যাক করুন।OptimisticLockException
থ্রো করা হয়।import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public Product updateProductPrice(Long id, Double newPrice) {
Product product = productRepository.findById(id).orElseThrow(() -> new RuntimeException("Product not found"));
product.setPrice(newPrice);
return productRepository.save(product);
}
}
Exception Handling:
try {
productService.updateProductPrice(1L, 200.0);
} catch (OptimisticLockException e) {
System.out.println("Conflict detected: " + e.getMessage());
}
Pessimistic Locking তখন ব্যবহৃত হয় যখন ডেটার সংঘর্ষের সম্ভাবনা বেশি থাকে। এটি ডেটাবেস লেভেলে লক তৈরি করে, যাতে অন্য ট্রানজ্যাকশন সেই ডেটা অ্যাক্সেস করতে না পারে যতক্ষণ না বর্তমান ট্রানজ্যাকশন সম্পূর্ণ হয়।
import jakarta.persistence.*;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public class ProductRepository {
@PersistenceContext
private EntityManager entityManager;
public Optional<Product> findProductWithPessimisticLock(Long id) {
return Optional.ofNullable(entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE));
}
}
LockModeType Options:
PESSIMISTIC_READ
: ডেটা পড়ার জন্য লক।PESSIMISTIC_WRITE
: ডেটা আপডেট বা ডিলিটের জন্য লক।PESSIMISTIC_FORCE_INCREMENT
: লক সহ ভার্সন আপডেট।import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductWithLock(Long id, Double newPrice) {
Product product = productRepository.findProductWithPessimisticLock(id)
.orElseThrow(() -> new RuntimeException("Product not found"));
product.setPrice(newPrice);
}
}
বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
---|---|---|
ব্যবহার ক্ষেত্র | সংঘর্ষের সম্ভাবনা কম। | সংঘর্ষের সম্ভাবনা বেশি। |
পারফরম্যান্স | লকিংয়ের জন্য অতিরিক্ত ওভারহেড নেই। | ডেটাবেস লকিং ওভারহেড বেশি। |
কনফ্লিক্ট হ্যান্ডলিং | ডেটা সংঘর্ষ হলে Exception থ্রো করে। | ডেটা সংঘর্ষ হওয়ার আগে লক করে প্রতিরোধ করে। |
Hibernate-এ Locking কৌশল ব্যবহার করে ডেটার কনসিস্টেন্সি এবং সঠিকতা নিশ্চিত করা যায়। Optimistic Locking পারফরম্যান্সে উন্নত হলেও, Pessimistic Locking ডেটা নিরাপত্তা নিশ্চিত করে। সঠিক ব্যবহারের জন্য অ্যাপ্লিকেশন কনটেক্সট অনুযায়ী Locking কৌশল বেছে নিতে হবে।
Read more